home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / upc12bs1.zip / UUCICO / dcplib.c < prev    next >
C/C++ Source or Header  |  1993-09-29  |  17KB  |  439 lines

  1. /*--------------------------------------------------------------------*/
  2. /*    d c p l i b . c                                                 */
  3. /*                                                                    */
  4. /*    DCP system-dependent library                                    */
  5. /*                                                                    */
  6. /*    Services provided by dcplib.c:                                  */
  7. /*                                                                    */
  8. /*    - login                                                         */
  9. /*    - UNIX commands simulation                                      */
  10. /*--------------------------------------------------------------------*/
  11.  
  12. /*--------------------------------------------------------------------*/
  13. /*    Changes Copyright (c) 1989-1993 by Kendra Electronic            */
  14. /*    Wonderworks.                                                    */
  15. /*                                                                    */
  16. /*    All rights reserved except those explicitly granted by the      */
  17. /*    UUPC/extended license agreement.                                */
  18. /*--------------------------------------------------------------------*/
  19.  
  20. /*--------------------------------------------------------------------*/
  21. /*    Copyright (c) Richard H. Lamb 1985, 1986, 1987                  */
  22. /*    Changes Copyright (c) Stuart Lynne 1987                         */
  23. /*--------------------------------------------------------------------*/
  24.  
  25. /*
  26.  *    $Id: dcplib.c 1.7 1993/09/29 04:52:03 ahd Exp $
  27.  *
  28.  *    $Log: dcplib.c $
  29.  * Revision 1.7  1993/09/29  04:52:03  ahd
  30.  * Make device name use standard modem file configuration prefix
  31.  *
  32.  * Revision 1.6  1993/09/20  04:48:25  ahd
  33.  * TCP/IP support from Dave Watt
  34.  * 't' protocol support
  35.  * OS/2 2.x support (BC++ 1.0 for OS/2)
  36.  *
  37.  * Revision 1.5  1993/07/24  03:40:55  ahd
  38.  * Correct #ifif to #ifel
  39.  *
  40.  * Revision 1.4  1993/07/22  23:22:27  ahd
  41.  * First pass at changes for Robert Denny's Windows 3.1 support
  42.  *
  43.  * Revision 1.3  1993/05/30  00:01:47  ahd
  44.  * Multiple commuications drivers support
  45.  *
  46.  *
  47.  * Updated:
  48.  *
  49.  *    14May89  - Added system name to login prompt - ahd
  50.  *               Added configuration file controlled user id, password
  51.  *               Added Kermit server option
  52.  *    17May89  - Redo login processing to time out after five minutes;
  53.  *               after all, we have to exit someday.                    ahd
  54.  *    22Sep89  - Add password file processing                           ahd
  55.  *    24Sep89  - Modify login() to issue only one wait command for up
  56.  *               to 32K seconds; this cuts down LOGFILE clutter.        ahd
  57.  *    01Oct89  - Re-do function headers to allow copying for function
  58.  *               prototypes in ulib.h                                   ahd
  59.  *    17Jan90  - Filter unprintable characters from logged userid and
  60.  *               password to prevent premature end of file.             ahd
  61.  *    18Jan90  - Alter processing of alternate shells to directly
  62.  *               invoke program instead of using system() call.         ahd
  63.  * 6  Sep 90   - Change logging of line data to printable               ahd
  64.  *    8 Sep 90 - Split ulib.c into dcplib.c and ulib.c                  ahd
  65.  *    8 Oct 90 - Break rmail.com and rnews.com out of uuio
  66.  *               Add FIXED_SPEED option for no-autobauding              ahd
  67.  *    10Nov 90 - Move sleep call into ssleep and rename                 ahd
  68.  */
  69.  
  70. /*--------------------------------------------------------------------*/
  71. /*                        System include files                        */
  72. /*--------------------------------------------------------------------*/
  73.  
  74. #include <ctype.h>
  75. #include <direct.h>
  76. #include <dos.h>
  77. #include <process.h>
  78. #include <stdio.h>
  79. #include <stdlib.h>
  80. #include <string.h>
  81. #include <sys/types.h>
  82. #include <time.h>
  83.  
  84. #ifdef __TURBOC__
  85. #include <sys/timeb.h>
  86. #endif
  87.  
  88. #if defined(_Windows)
  89. #include <windows.h>
  90. #endif
  91.  
  92. /*--------------------------------------------------------------------*/
  93. /*                    UUPC/extended include files                     */
  94. /*--------------------------------------------------------------------*/
  95.  
  96. #include "lib.h"
  97. #include "arpadate.h"
  98. #include "dcp.h"
  99. #include "dcplib.h"
  100. #include "dcpsys.h"
  101. #include "hlib.h"
  102. #include "hostable.h"
  103. #include "import.h"
  104. #include "modem.h"
  105. #include "pushpop.h"
  106. #include "security.h"
  107. #include "ssleep.h"
  108. #include "commlib.h"
  109. #include "usertabl.h"
  110. #include "timestmp.h"
  111.  
  112. /*--------------------------------------------------------------------*/
  113. /*        Define current file name for panic() and printerr()         */
  114. /*--------------------------------------------------------------------*/
  115.  
  116. #if !defined(_Windows)
  117. currentfile();
  118. #endif
  119.  
  120. /*--------------------------------------------------------------------*/
  121. /*                    Internal function prototypes                    */
  122. /*--------------------------------------------------------------------*/
  123.  
  124. static void LoginShell( const   struct UserTable *userp );
  125.  
  126. void motd( const char *fname, char *buf, const int bufsiz );
  127.  
  128. /*--------------------------------------------------------------------*/
  129. /*    l o g i n                                                       */
  130. /*                                                                    */
  131. /*    Login handler                                                   */
  132. /*--------------------------------------------------------------------*/
  133.  
  134. boolean login(void)
  135. {
  136.    char line[BUFSIZ];                  /* Allow for long domain names!  */
  137.    char user[50];
  138.    char pswd[50];
  139.    char attempts = 0;                  /* Allows login tries         */
  140.    char *token;                        /* Pointer to returned token  */
  141.    struct UserTable *userp;
  142.  
  143. #if defined(_Windows)
  144.    WORD wVersion;
  145. #endif
  146.  
  147.    if ( E_banner != NULL )
  148.       motd( E_banner, line, sizeof line );
  149.  
  150. /*--------------------------------------------------------------------*/
  151. /*    Our modem is now connected.  Begin actual login processing      */
  152. /*    by displaying a banner.                                         */
  153. /*--------------------------------------------------------------------*/
  154.  
  155. #if defined(_Windows)
  156.     wVersion = LOWORD(GetVersion());
  157.     sprintf(line, "\r\n\nMS-Windows(TM) %d.%02d with %s %s (%s) (%s)\r\n",
  158.          (WORD)(LOBYTE(wVersion)),
  159.          (WORD)(HIBYTE(wVersion)),
  160.           compilep,
  161.           compilev,
  162.          E_domain,
  163.          M_device);           // Print a hello message
  164.  
  165. #else /* not Windows */
  166.  
  167.    sprintf(line,"\r\n\n%s %d.%02d with %s %s (%s) (%s)\r\n",
  168. #ifdef WIN32
  169.             "Windows NT(TM)",
  170.             _winmajor,
  171.             _winminor,
  172. #elif defined(__OS2__)
  173.             "OS/2(R)",
  174.             (int) _osmajor / 10,
  175.             _osminor,
  176. #elif defined( __TURBOC__ )
  177.             "MS-DOS(R)",
  178.             _osmajor,
  179.             _osminor,
  180. #else
  181.             (_osmode == DOS_MODE) ? "DOS" : "OS/2(R)" ,
  182.             (_osmode == DOS_MODE) ? (int) _osmajor : ((int) _osmajor / 10 ),
  183.             _osminor,
  184. #endif
  185.             compilep,
  186.             compilev,
  187.             E_domain,
  188.             M_device); /* Print a hello message            */
  189. #endif
  190.  
  191.    wmsg(line,0);
  192.    ddelay(250);
  193.  
  194. /*--------------------------------------------------------------------*/
  195. /*    Display a login prompt until we get a printable character or    */
  196. /*    the login times out                                             */
  197. /*--------------------------------------------------------------------*/
  198.  
  199.    for ( attempts = 0; attempts < 5 ; attempts++ )
  200.    {
  201.       boolean invalid = TRUE;
  202.       while (invalid)         /* Spin for a user id or timeout       */
  203.       {
  204.          wmsg("\r\nlogin: ", 0);
  205.          strcpy(user,"");
  206.          if (rmsg(user, 2, 30, sizeof user) == TIMEOUT)
  207.                                     /* Did the user enter data?  */
  208.             return FALSE;   /* No --> Give up                */
  209.  
  210.          if (equal(user,"NO CARRIER"))
  211.             return FALSE;
  212.  
  213.          token = user;
  214.          while ((*token != '\0') && invalid) /* Ignore empty lines   */
  215.             invalid = ! isgraph(*token++);
  216.       } /* while */
  217.  
  218.       printmsg(14, "login: login=%s", user);
  219.  
  220. /*--------------------------------------------------------------------*/
  221. /*               We have a user id, now get a password                */
  222. /*--------------------------------------------------------------------*/
  223.  
  224.       wmsg("\r\nPassword: ", 0);
  225.       strcpy(pswd,"");
  226.       if (rmsg(pswd, 0, 30, sizeof pswd) == TIMEOUT)
  227.          return FALSE;
  228.  
  229. /*--------------------------------------------------------------------*/
  230. /*       Zap unprintable characters before we log the password        */
  231. /*--------------------------------------------------------------------*/
  232.  
  233.       printmsg(14, "login: password=%s", pswd);
  234.  
  235. /*--------------------------------------------------------------------*/
  236. /*                 Validate the user id and passowrd                  */
  237. /*--------------------------------------------------------------------*/
  238.  
  239.       userp = checkuser(user);         /* Locate user id in host table  */
  240.  
  241.       if (userp == BADUSER)            /* Does user id exist?           */
  242.       {                                /* No --> Notify the user        */
  243.          wmsg("\r\nlogin failed",0);
  244.  
  245.          token = user;
  246.          while (!isalnum( *token ) && (*token !=  '\0'))
  247.             token ++;                  /* Scan for first alpha-numeric  */
  248.  
  249.          if (*token != '\0')           /* If at least one good char     */
  250.             printmsg(0,"login: login for user %s failed, bad user id",
  251.                   user);               /* Log the error for ourselves   */
  252.       }
  253.       else if ( equal(pswd,userp->password))   /* Correct password?     */
  254.       {                                /* Yes --> Log the user "in"     */
  255.                    /*   . . ..+....1....  +....2....+....3....  + .   */
  256.          sprintf(line,"\r\n\nWelcome to %s; login complete at %s\r\n",
  257.                   E_domain, arpadate());
  258.          wmsg(line, 0);
  259.          printmsg(0,"login: login user %s (%s) at %s",
  260.                      userp->uid, userp->realname, arpadate());
  261.  
  262.          if equal(userp->sh,UUCPSHELL) /* Standard uucp shell?       */
  263.          {
  264.             securep = userp->hsecure;
  265.             printmsg(5,"Processing user via %s", UUCPSHELL);
  266.             return TRUE;            /* Yes --> Startup the machine   */
  267.          }
  268.          else {                     /* No --> run special shell      */
  269.  
  270.             if ( E_motd != NULL )
  271.                motd( E_motd, line, sizeof line );
  272.             LoginShell( userp );
  273.             return FALSE;   /* Hang up phone and exit        */
  274.          }
  275.       }
  276.       else {                        /* Password was wrong.  Report   */
  277.          wmsg("\r\nlogin failed",0);
  278.          printmsg(0,"login: login user %s (%s) failed, bad password %s",
  279.                   userp->uid, userp->realname, pswd);
  280.       }
  281.    }  /* for */
  282.  
  283. /*-----------------------------------------------------------------*/
  284. /*    If we fall through the loop, we have an excessive number of  */
  285. /*    login attempts; hangup the telephone and try again.          */
  286. /*-----------------------------------------------------------------*/
  287.  
  288.    return FALSE;                    /* Exit processing            */
  289.  
  290. } /*login*/
  291.  
  292. /*--------------------------------------------------------------------*/
  293. /*    l o g i n b y p a s s                                           */
  294. /*                                                                    */
  295. /*    Initialize user setup when login is bypassed                    */
  296. /*--------------------------------------------------------------------*/
  297.  
  298. boolean loginbypass(const char *user)
  299. {
  300.    struct UserTable *userp;
  301.    char line[BUFSIZ];                  /* Allow for long domain names!  */
  302.  
  303.    printmsg(14, "loginbypass: login=%s", user);
  304.  
  305. /*--------------------------------------------------------------------*/
  306. /*                 Validate the user id                               */
  307. /*--------------------------------------------------------------------*/
  308.  
  309.    userp = checkuser(user);         /* Locate user id in host table  */
  310.  
  311.    if (userp == BADUSER)            /* Does user id exist?           */
  312.    {                                /* No --> Notify the user        */
  313.       wmsg("\r\nUUCICO login failed",0);
  314.  
  315.       printmsg(0,"loginbypass: login for user %s failed, bad user id",
  316.                user);               /* Log the error for ourselves   */
  317.       return FALSE;                 /* Hang up phone and exit        */
  318.    }
  319.    else {
  320.                                     /* Yes --> Log the user "in"     */
  321.                 /*   . . ..+....1....  +....2....+....3....  + .   */
  322.       sprintf(line,"\r\n\nWelcome to %s; login complete at %s\r\n",
  323.                E_domain, arpadate());
  324.       wmsg(line, 0);
  325.       printmsg(0,"loginbypass: login user %s (%s) at %s",
  326.                   userp->uid, userp->realname, arpadate());
  327.  
  328.       if equal(userp->sh,UUCPSHELL) /* Standard uucp shell?       */
  329.       {
  330.          securep = userp->hsecure;
  331.          return TRUE;            /* Yes --> Startup the machine   */
  332.       } /* if equal(userp->sh,UUCPSHELL) */
  333.       else {                     /* No --> run special shell      */
  334.          LoginShell( userp );
  335.          return FALSE;           /* Hang up phone and exit        */
  336.       } /* else */
  337.    } /* else */
  338.  
  339. } /*loginbypass*/
  340.  
  341. /*--------------------------------------------------------------------*/
  342. /*    L o g i n S h e l l                                             */
  343. /*                                                                    */
  344. /*    Execute a non-default remote user shell                         */
  345. /*--------------------------------------------------------------------*/
  346.  
  347. static void LoginShell( const   struct UserTable *userp )
  348. {
  349.  
  350. #if defined(_Windows)
  351.         char line[128];
  352.         //
  353.         // No special shell support under Windows, sorry!
  354.         //
  355.         sprintf(line,
  356.            "login: special shell %s not supported. Goodbye.\r\n",
  357.                 userp->sh);
  358.         wmsg(line, 0);
  359.    printmsg(0, "Login with special shell %s, not supported.", userp->sh);
  360.    return;
  361.  
  362. #else
  363.  
  364.    char *shellstring;
  365.    char *path;
  366.    char *args;
  367.    int   rc;
  368.  
  369. /*--------------------------------------------------------------------*/
  370. /*              Get the program to run and its arguments              */
  371. /*--------------------------------------------------------------------*/
  372.  
  373.    shellstring = strdup(userp->sh);
  374.                               /* Copy user shell for parsing   */
  375.    path = strtok(shellstring," \t");   /* Get program name  */
  376.    args = strtok(NULL,"");    /* Get rest of arg string     */
  377.  
  378.    printmsg(1,"LoginShell: Invoking %s in directory %s",
  379.          userp->sh, userp->homedir);
  380.  
  381.    ddelay(250);            /* Wait for port to stablize     */
  382.  
  383. /*--------------------------------------------------------------------*/
  384. /*       Run the requested program in the user's home directory       */
  385. /*--------------------------------------------------------------------*/
  386.  
  387.    PushDir(userp->homedir);/* Switch to user's home dir     */
  388.    if (args == NULL)
  389.       rc = spawnl(P_WAIT, path, path, NULL);
  390.    else
  391.       rc = spawnl(P_WAIT, path, path, args, NULL);
  392.  
  393.    PopDir();               /* Return to original directory  */
  394.  
  395. /*--------------------------------------------------------------------*/
  396. /*                     Report any errors we found                     */
  397. /*--------------------------------------------------------------------*/
  398.  
  399.    if ( rc < 0 )           /* Error condition?              */
  400.    {                        /* Yes --> Report it to the user */
  401.       printmsg(0,"LoginShell: Unable to execute user shell");
  402.       printerr(path);
  403.    }
  404.    else                    /* No --> Report normal result   */
  405.       printmsg(rc == 0 ? 4 : 0,"LoginShell: %s return code is %d",
  406.                path,
  407.                rc);
  408.  
  409. #endif
  410.  
  411. } /* LoginShell */
  412.  
  413. /*--------------------------------------------------------------------*/
  414. /*    m o t d                                                         */
  415. /*                                                                    */
  416. /*    Display a message of the day to the remote login                */
  417. /*--------------------------------------------------------------------*/
  418.  
  419. void motd( const char *fname, char *buf, const int bufsiz )
  420. {
  421.    FILE *stream = FOPEN( fname, "r", BINARY_MODE );  /* Leave CRLF in data */
  422.  
  423.    if ( stream == NULL )
  424.    {
  425.       perror( fname );
  426.       wmsg( fname,0 );
  427.       wmsg( ": ", 0);
  428.       wmsg( strerror( errno ),0);
  429.       wmsg( "\n\r",0);
  430.       return;
  431.    } /* if ( stream == NULL ) */
  432.  
  433.    while( fgets( buf, bufsiz, stream ) != NULL )
  434.       wmsg( buf, 0 );
  435.  
  436.    fclose( stream );
  437.  
  438. } /* motd */
  439.